package zone

import (
	"bytes"
	"encoding/gob"
	"github.com/Unixeno/TheMoon/model"
	"github.com/Unixeno/TheMoon/moon/core/context"
	"github.com/Unixeno/TheMoon/moon/zone/storage"
	"github.com/Unixeno/TheMoon/pool"
	message "github.com/Unixeno/TheMoon/radio/protos"
	"github.com/rs/xid"
	"time"
)

const EventBucket = "events"

type event struct {
	Level   message.Event_EventLevel
	Message string
	MoonID  string
	Source  string
	Time    int64
}

type postman struct {
	level     message.Event_EventLevel
	eventChan chan event
}

func newPostman() *postman {
	p := &postman{
		level:     message.Event_Info,
		eventChan: make(chan event, 8),
	}
	storage.CreateBucket(EventBucket)
	go p.sender()
	return p
}

func (p *postman) sender() {
	for {
		// 从数据库内取出一个进行发送
		key, value, err := storage.GetOne(EventBucket)
		if err != nil {
			logger.WithError(err).Error("failed to get event from db")
		}
		if key == nil {
			// 没有消息了
			time.Sleep(time.Second)
		} else {
			var e event
			_ = gob.NewDecoder(bytes.NewBuffer(value)).Decode(&e)

			msg := model.NewMessage(ModuleName, "inspector")
			eventMessage := &message.Event{
				Source:  e.Source,
				Level:   e.Level,
				Message: e.Message,
				Time:    e.Time,
			}
			msg.Content, _ = eventMessage.Marshal()

			_, err = context.SyncSendMessage(msg, time.Second*3)
			if err == nil {
				_ = storage.Delete(EventBucket, key)
			} else {
				time.Sleep(time.Second)
			}
		}
	}
}

// 触发一个事件
func (p *postman) TriggerEvent(level message.Event_EventLevel, source string, message string) {
	e := event{
		Level:   level,
		Source:  source,
		Message: message,
		Time:    time.Now().Unix(),
	}
	poolBuffer := pool.Fixed64KPool.Get().([]byte)
	buffer := bytes.NewBuffer(poolBuffer)
	// 将消息存入db
	buffer.Reset()
	gob.NewEncoder(buffer).Encode(e)
	storage.Put(EventBucket, xid.New().Bytes(), buffer.Bytes())
	pool.Fixed64KPool.Put(poolBuffer)
}
